#include<bits/stdc++.h>
using namespace std;
const int maxn1=1e5+5;
const int maxn2=1e6+5;
vector<int> vc[maxn1];
struct Node{
    double d;
    int v,a;
}car[maxn1];
double p[maxn1];
bool visp[maxn2],visn[maxn1];
int cnt[maxn2];
bool find(vector<int> &vc,int target){
    for(int i=0; i<vc.size(); i++){
        if(vc[i]==target)return true;
    }
    return false;
}
int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    ios::sync_with_stdio(0);
    int t;
    cin>>t;
    while(t--){
        int n,m,L,V;
        cin>>n>>m>>L>>V;
        for(int i=1; i<=n; i++){
            cin>>car[i].d>>car[i].v>>car[i].a;
        }
        for(int i=1; i<=m; i++){
            cin>>p[i];
        }
        for(int i=1; i<=n; i++){
            if(car[i].a==0){
                if(car[i].v>V){
                    int t=lower_bound(p+1,p+m+1,car[i].d)-p;
                    if(t!=-1){
                        for(int j=t; j<=m; j++){
                            vc[i].push_back(p[j]);
                        }
                    }
                }
            }else if(car[i].a>0){
                int t;
                double s=0;
                if(car[i].v<V){
                    s=(V*V-car[i].v*car[i].v)/(double)(2*car[i].a);
                }else if(car[i].v==V)s=1;
                double S=car[i].d+s;
                if(S<=L){
                    t=upper_bound(p+1,p+m+1,S)-p;
                    if(t!=-1){
                        for(int j=t; j<=m; j++){
                            vc[i].push_back(p[j]);
                        }
                    }
                }
            }else if(car[i].a<0){
                if(car[i].v>V){
                    double s=(V*V-car[i].v*car[i].v)/(double)(2*car[i].a);
                    double S=car[i].d+s;
                    if(S<=L){
                        int t=lower_bound(p+1,p+m+1,S)-p;
                        for(int j=t-1; p[j]>=car[i].d; j--){
                            vc[i].push_back(p[j]);
                        }
                    }
                }
            }
        }
        int ans=0;
        int on=0;
        for(int i=1; i<=n; i++){
            int len=vc[i].size();
            if(len){
                ans++;
                for(auto it:vc[i]){
                    cnt[it]++;
                }
            }
        }
        for(int i=1; i<=n; i++){
            int len=vc[i].size();
            if(len==1){
                on++;
                visp[vc[i][0]]=true;
                visn[i]=true;
            }else if(len>1){
                for(auto it:vc[i]){
                    if(!visp[it]){
                        bool f=false;
                        for(int j=1; j<=n; j++){
                            if(i==j)continue;
                            if(find(vc[j],it) && !visn[j]){
                                on++;
                                visn[j]=true;
                                f=true;
                                for(int k=i+1; k<=n; k++){
                                    if(find(vc[k],it))visn[k]=true;
                                }
                                visp[it]=true;
                            }
                        }
                    }
                }
            }
        }
        cout<<ans<<' '<<n-on<<endl;
        memset(car,0,sizeof car);
        for(int i=1; i<=n; i++)vc[i].clear();
        memset(p,0,sizeof p);
        memset(cnt,0,sizeof cnt);
    }
    return 0;
}
